package graphing;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import model.Cohort;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYDotRenderer;
import org.jfree.data.xy.XYDataItem;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import parsing.Indices2011;
import parsing.RaceResultParsingInformation;

public class AnalysisController {

	public static void main(String[] arguments) {
		File turkeyTrot2011File = new File(
				"E:\\aThom\\memories\\Turkey Trot Times 2011.txt");
		Vector<String> fileContents = importFile(turkeyTrot2011File);
		RunDataResult fullResults = parseFile(fileContents, Indices2011.indices2011) ;
		String outputDirectory = "E:\\aThom\\memories\\" ;
//		plotXYLineOfAllRunners(fullResults.getRunners(), outputDirectory)  ;
		plotXYScatterOfMenAndWomen(fullResults.getRunners(), outputDirectory) ;
		plotThomsTime(fullResults.getRunners(), outputDirectory) ; 
		System.out.println("Program completed. Look for output in " + outputDirectory) ; 
	}

	private static void plotThomsTime(List<RunnerWithResult> allRunners, String outputDirectory) {
        XYSeries allMenSeries = new XYSeries("All Men") ; 
        XYSeries all59sSeries = new XYSeries("All Men 59") ; 
        XYSeries thomSeries = new XYSeries("Thom") ;
        XYSeries allSeries = new XYSeries("All") ; 
        for (Iterator<RunnerWithResult> runnersIterator = allRunners.iterator(); runnersIterator.hasNext();) {
			RunnerWithResult runner = runnersIterator.next();
			double age = runner.getAge(2011) ; 
			int time = runner.getTimeInSeconds() ;
			if(age > 0) {
				XYDataItem item = new XYDataItem(age, time) ; 
				if(isFriend(runner)) {
					thomSeries.add(age, time) ; 
				}
				else if(runner.getAge(2011) == 59 && runner.isMale()) {
					all59sSeries.add(age, time) ; 
				}
				else if(runner.isMale()) {
					allMenSeries.add(age, time) ; 
				}
				allSeries.add(item) ; 
			}
		}
        XYSeriesCollection menDataset = new XYSeriesCollection(allMenSeries) ;
        XYSeriesCollection men59Dataset = new XYSeriesCollection(all59sSeries) ;
        XYSeriesCollection thomDataset = new XYSeriesCollection(thomSeries) ;
        XYSeriesCollection allDataset = new XYSeriesCollection(allSeries) ;
        NumberAxis ageAxis = new NumberAxis("Age (years)") ; 
        ageAxis.setAutoRangeIncludesZero(false) ;
        NumberAxis timeAxis = new NumberAxis("Time (seconds)");
        timeAxis.setAutoRangeIncludesZero(false) ; 
        XYDotRenderer menRenderer = new XYDotRenderer() ;
        menRenderer.setSeriesPaint(0, Color.CYAN) ;
        menRenderer.setDotHeight(3) ; 
        menRenderer.setDotWidth(3) ;
        XYDotRenderer men59Renderer = new XYDotRenderer() ;
        men59Renderer.setSeriesPaint(0, Color.GREEN) ;
        men59Renderer.setDotHeight(5) ; 
        men59Renderer.setDotWidth(5) ;
        XYDotRenderer thomRenderer = new XYDotRenderer() ;
        thomRenderer.setSeriesPaint(0, Color.BLUE) ;
        thomRenderer.setDotHeight(8) ; 
        thomRenderer.setDotWidth(8) ;
        XYDotRenderer allRenderer = new XYDotRenderer() ;
        allRenderer.setSeriesPaint(0, Color.PINK) ;
        allRenderer.setDotHeight(3) ; 
        allRenderer.setDotWidth(3) ;

        final XYPlot plot = new XYPlot(thomDataset, ageAxis, timeAxis, thomRenderer);
        plot.setDataset(1, men59Dataset) ; 
        plot.setRenderer(1, men59Renderer) ; 
        plot.setDataset(2, menDataset) ; 
        plot.setRenderer(2, menRenderer) ; 
        plot.setDataset(3, allDataset) ; 
        plot.setRenderer(3, allRenderer) ; 
		// Draw the plot in a jpg or png
         
        JFreeChart scatterPlotChart = new JFreeChart(plot) ; 
        plot.setOrientation(PlotOrientation.HORIZONTAL) ; 
        scatterPlotChart.setTitle("Turkey Trot 2011") ; 
        	// ChartFactory.createScatterPlot("Turkey Trot 2011", "Age (years)", "Time (seconds)", dataset, PlotOrientation.HORIZONTAL, false, false, false) ;
        try {
        	int height = 800 ; 
        	int width = 1500 ; 
            ChartUtilities.saveChartAsPNG(new File(outputDirectory + "thomTurkeyTrot.png"), scatterPlotChart, width, height);
        } catch (IOException e) {
            System.err.println("Problem occurred creating chart.");
        }
        
		
	}
	
	private static boolean isFriend(RunnerWithResult runner) {
		boolean isFriend = false ;
		isFriend = runner.getName().contains("Burnett") && runner.getAge(2022) == 59 ;
		isFriend = isFriend || runner.getName().contains("Pajda") ;
		isFriend = isFriend || runner.getName().contains("Paradiso") ;
		isFriend = isFriend || runner.getName().contains("Ragione") ;
		isFriend = isFriend || runner.getName().contains("Bruce Carter") ;
		isFriend = isFriend || runner.getName().contains("Melissa Carter") ;
		isFriend = isFriend || runner.getName().contains("Wailand") ;
		isFriend = isFriend || runner.getName().contains("Omilan") ;
		
		return isFriend ; 
	}
	
	private static void plotXYScatterOfMenAndWomen(List<RunnerWithResult> allRunners, String outputDirectory) {
		// Load the series with data
        XYSeries allMenSeries = new XYSeries("All Men") ; 
        XYSeries allWomenSeries = new XYSeries("All Women") ; 
        for (Iterator<RunnerWithResult> runnersIterator = allRunners.iterator(); runnersIterator.hasNext();) {
			RunnerWithResult runner = runnersIterator.next();
			double age = runner.getAge(2011) ; 
			int time = runner.getTimeInSeconds() ;
			if(age > 0) {
				if(runner.isMale()) {
					allMenSeries.add(age - 0.25, time) ; 
				}
				else {
					allWomenSeries.add(age + 0.25, time) ; 
				}
			}
		}
        XYSeriesCollection menDataset = new XYSeriesCollection(allMenSeries) ;
        XYSeriesCollection womenDataset = new XYSeriesCollection(allWomenSeries) ;
        NumberAxis ageAxis = new NumberAxis("Age (years)") ; 
        NumberAxis timeAxis = new NumberAxis("Time (seconds)");
        XYDotRenderer menRenderer = new XYDotRenderer() ;
        menRenderer.setSeriesPaint(0, Color.CYAN) ;
        menRenderer.setDotHeight(5) ; 
        menRenderer.setDotWidth(5) ;
        XYDotRenderer womenRenderer = new XYDotRenderer() ;
        womenRenderer.setSeriesPaint(0, Color.RED) ;
        womenRenderer.setDotHeight(5) ; 
        womenRenderer.setDotWidth(5) ;
        final XYPlot plot = new XYPlot(menDataset, ageAxis, timeAxis, menRenderer);
        plot.setDataset(1, womenDataset) ; 
        plot.setRenderer(1, womenRenderer) ;
        
        plot.setOrientation(PlotOrientation.HORIZONTAL) ;
        ageAxis.setAutoRangeIncludesZero(false) ; 
        timeAxis.setAutoRangeIncludesZero(false) ; 
		// Draw the plot in a jpg or png
         
        JFreeChart scatterPlotChart = new JFreeChart(plot) ; 
        scatterPlotChart.setTitle("Turkey Trot 2011") ; 
        	// ChartFactory.createScatterPlot("Turkey Trot 2011", "Age (years)", "Time (seconds)", dataset, PlotOrientation.HORIZONTAL, false, false, false) ;
        try {
        	int height = 800 ; 
        	int width = 1500 ; 
            ChartUtilities.saveChartAsPNG(new File(outputDirectory + "doubleScatter.png"), scatterPlotChart, width, height);
        } catch (IOException e) {
            System.err.println("Problem occurred creating chart.");
        }
        
	}

	private static void plotXYLineOfAllRunners(List<RunnerWithResult> allRunners, String outputDirectory) {
        //         Create a simple XY chart
        XYSeries ageVsTimeSeries = new XYSeries("2011");
        for (Iterator<RunnerWithResult> runnersIterator = allRunners.iterator(); runnersIterator.hasNext();) {
			RunnerWithResult runner = runnersIterator.next();
			int age = runner.getAge(2011) ; 
			XYDataItem dataItem = new XYDataItem(age, runner.getTimeInSeconds()) ;
			if(age > 0) {
				ageVsTimeSeries.add(dataItem) ;
			}
		}
        //         Add the series to your data set
        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(ageVsTimeSeries);
        //         Generate the graph
        JFreeChart xyLineChart = ChartFactory.createXYLineChart("Turkey Trot 2011", // Title
                "Age (years)", // x-axis Label
                "Time (seconds)", // y-axis Label
                dataset, // Dataset
                PlotOrientation.VERTICAL, // Plot Orientation
                true, // Show Legend
                true, // Use tooltips
                false // Configure chart to generate URLs?
            );
        JFreeChart areaChart = ChartFactory.createXYAreaChart("Area Chart", "Age", "Time", dataset, PlotOrientation.VERTICAL, false, false, false) ; 
        JFreeChart scatterPlotChart = ChartFactory.createScatterPlot("Turkey Trot 2011", "Age (years)", "Time (seconds)", dataset, PlotOrientation.HORIZONTAL, false, false, false) ;
        Plot scatterPlot = scatterPlotChart.getPlot() ;
        try {
        	int height = 800 ; 
        	int width = 1500 ; 
            ChartUtilities.saveChartAsPNG(new File(outputDirectory + "testXYLine.png"), xyLineChart, width, height);
            ChartUtilities.saveChartAsPNG(new File(outputDirectory + "testXYArea.png"), areaChart, width, height);
            ChartUtilities.saveChartAsPNG(new File(outputDirectory + "testScatter.png"), scatterPlotChart, width, height);
        } catch (IOException e) {
            System.err.println("Problem occurred creating chart.");
        }
    }

// Separate colors
//	CategoryItemRenderer renderer = plot.getRenderer();
//	renderer.setSeriesPaint(0, Color.green);
//	renderer.setSeriesPaint(1, Color.red);
	// and so on...
	
//	NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
//	rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 	
	
	public static RunDataResult parseFile(Vector<String> fileContents, RaceResultParsingInformation parsingInformation) {
		Set<Cohort> runningCohorts = new HashSet<Cohort>() ; 
		List<RunnerWithResult> runners = new ArrayList<RunnerWithResult>() ;
		System.out.println("First line read: " + fileContents.elementAt(12)) ;
		for (int i = parsingInformation.getHeaderLineCount() ; i < fileContents.size() ; i++) { // Skip first 12 lines
			String dataLine = fileContents.elementAt(i) ; 
			if(dataLine.length() > parsingInformation.getStateEnd() - 1) {
			RunnerWithResult newRunner = new RunnerWithResult(fileContents.elementAt(i), parsingInformation) ; 
			runners.add(newRunner) ; 
			Cohort newCohort = new Cohort(fileContents.elementAt(i), Indices2011.indices2011) ;
			 if(newCohort != null && newCohort.isValid()) {
				 runningCohorts.add(newCohort) ;
			 }
			}
			else {
				System.out.println("invalid dataLine: " + dataLine) ; 
			}
		}
		System.out.println("Last line read: " + fileContents.elementAt(fileContents.size()-1)) ;
		System.out.println("Loaded file. Runner count: " + runners.size() + " and cohort count: " + runningCohorts.size()) ; 
		RunDataResult fullResult = new RunDataResult() ; 
		fullResult.setRunnerCohorts(runningCohorts) ; 
		fullResult.setRunners(runners) ;
		return fullResult ;
	}

	public static Vector<String> importFile(File aFile) {
		Vector<String> contents = new Vector<String>();
		try {
			BufferedReader input = new BufferedReader(new FileReader(aFile));
			try {
				String line = null;
				while ((line = input.readLine()) != null) {
					contents.add(line);
				}
			} finally {
				input.close();
			}
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}

		return contents;
	}
}
